home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / bytesc88.arc / CC12.C < prev    next >
Text File  |  1987-10-04  |  8KB  |  306 lines

  1. /*
  2. ** Small C - 8088/8086 version - modified by R. Grehan, BYTE Magazine
  3. ** open an include file
  4. */
  5. doinclude()  {
  6.   char *cp;
  7.   blanks();            /* skip over to name */
  8.   switch (*lptr) {
  9.     case '"': case '<': cp = ++lptr;
  10.     while(*cp) {
  11.       switch(*cp) {case '"': case '>': *cp=NULL;}
  12.       ++cp;
  13.       }
  14.     }
  15.   if((input2=fopen(lptr,"r"))==NULL) {
  16.     input2=EOF;
  17.     error("open failure on include file");
  18.     }
  19.   kill();            /* clear rest of line */
  20.                 /* so next read will come from */
  21.                 /* new file (if open) */
  22.   }
  23.  
  24. /*
  25. ** test for global declarations
  26. */
  27. dodeclare(class) int class; {
  28.   if(amatch("char",4)) {
  29.     declglb(CCHAR, class);
  30.     ns();
  31.     return 1;
  32.     }
  33.   else if((amatch("int",3))|(class==EXTERNAL)) {
  34.     declglb(CINT, class);
  35.     ns();
  36.     return 1;
  37.     }
  38.   return 0;
  39.   }
  40.  
  41. /*
  42. ** delcare a static variable
  43. */
  44. declglb(type, class)  int type, class; {
  45.   int k, j;
  46.   while(1) {
  47.     if(endst()) return;            /* do line */
  48.     if(match("(*")|match("*")) {
  49.       j=POINTER;
  50.       k=0;
  51.       }
  52.     else {
  53.       j=VARIABLE;
  54.       k=1;
  55.       }
  56.     if (symname(ssname, YES)==0) illname();
  57.     if(findglb(ssname)) multidef(ssname);
  58.     if(match(")")) ;
  59.     if(match("()")) j=FUNCTION;
  60.     else if (match("[")) {
  61.       paerror(j);
  62.       k=needsub();            /* get size */
  63.       j=ARRAY;                /* !0=array */
  64.       }
  65. /* Following changed for MASM */
  66.     if(class==EXTERNAL) { external(ssname);
  67.      if(j==FUNCTION) { if(k!=0) ol("NEAR"); else ol("WORD"); }
  68.       else
  69.       if ((type==CCHAR)&(k!=0)) ol("BYTE"); else ol("WORD");
  70.     }
  71.     else if(j!=FUNCTION) j=initials(type>>2, j, k);
  72.     addsym(ssname, j, type, k, &glbptr, class);
  73.     if (match(",")==0) return;        /* more? */
  74.     }
  75.   }
  76.  
  77. /*
  78. ** declare local variables
  79. */
  80. declloc(typ)  int typ;  {
  81.   int k,j;
  82.   if(swactive) error("not allowed in switch");
  83. #ifdef STGOTO
  84.   if(noloc) error("not allowed with goto");
  85. #endif
  86.   if(declared < 0) error("must declare first in block");
  87.   while(1) {
  88.     while(1) {
  89.       if(endst()) return;
  90.       if(match("*")) j=POINTER;
  91.       else           j=VARIABLE;
  92.       if (symname(ssname, YES)==0) illname();
  93.       /* no multidef check, block-locals are together */
  94.       k=BPW;
  95.       if (match("[")) {
  96.         paerror(j);
  97.         if(k=needsub()) {
  98.           j=ARRAY;
  99.           if(typ==CINT)k=k<<LBPW;
  100.           }
  101.         else {j=POINTER; k=BPW;}
  102.         }
  103.       else if((typ==CCHAR)&(j==VARIABLE)) k=SBPC;
  104.       declared = declared + k;
  105.       addsym(ssname, j, typ, csp - declared, &locptr, AUTOMATIC);
  106.       break;
  107.       }
  108.     if (match(",")==0) return;
  109.     }
  110.   }
  111.  
  112. /*
  113. ** test for pointer array (unsupported)
  114. */
  115. paerror(j) int j; {
  116.   if(j==POINTER) error("no pointer arrays");
  117.   }
  118.  
  119. /*
  120. ** initialize global objects
  121. */
  122. initials(size, ident, dim) int size, ident, dim; {
  123.   int savedim;
  124.   litptr=0;
  125.   if(dim==0) dim = -1;
  126.   savedim=dim;
  127.  
  128. /*  Had to change entry(); to following stuff to keep
  129. ** MASM happy.  It doesn't like colons preceding DW and
  130. ** DB.  Sheesh.  --RG
  131. **  entry();
  132. */
  133.   ot(" PUBLIC ");
  134.   outlab(ssname);
  135.   nl();
  136.   outlab(ssname);
  137.   
  138.   if(match("=")) {
  139.     if(match("{")) {
  140.       while(dim) {
  141.         init(size, ident, &dim);
  142.         if(match(",")==0) break;
  143.         }
  144.       needtoken("}");
  145.       }
  146.     else init(size, ident, &dim);
  147.     }
  148.   if((dim == -1)&(dim==savedim)) {
  149.      stowlit(0, size=BPW);
  150.     ident=POINTER;
  151.     }
  152.   dumplits(size);
  153.   dumpzero(size, dim);
  154.   return ident;
  155.   }
  156.  
  157. /*
  158. ** evaluate one initializer
  159. */
  160. init(size, ident, dim) int size, ident, *dim; {
  161.   int value;
  162.   if(qstr(&value)) {
  163.     if((ident==VARIABLE)|(size!=1))
  164.       error("must assign to char pointer or array");
  165.     *dim = *dim - (litptr - value);
  166.     if(ident==POINTER) point();
  167.     }
  168.   else if(constexpr(&value)) {
  169.     if(ident==POINTER) error("cannot assign to pointer");
  170.     stowlit(value, size);
  171.     *dim = *dim - 1;
  172.     }
  173.   }
  174.  
  175. /*
  176. ** get required array size
  177. */
  178. needsub()  {
  179.   int val;
  180.   if(match("]")) return 0;    /* null size */
  181.   if (constexpr(&val)==0) val=1;
  182.   if (val<0) {
  183.     error("negative size illegal");
  184.     val = -val;
  185.     }
  186.   needtoken("]");        /* force single dimension */
  187.   return val;            /* and return size */
  188.   }
  189.  
  190. /*
  191. ** begin a function
  192. **
  193. ** called from "parse" and tries to make a function
  194. ** out of the following text
  195. **
  196. */
  197. newfunc()  {
  198.   char *ptr;
  199. #ifdef STGOTO
  200.   nogo  =            /* enable goto statements */
  201.   noloc = 0;            /* enable block-local declarations */
  202. #endif
  203.   lastst=            /* no statement yet */
  204.   litptr=0;            /* clear lit pool */
  205.   litlab=getlabel();        /* label next lit pool */
  206.   locptr=STARTLOC;        /* clear local variables */
  207.   if(monitor) lout(line, stderr);
  208.   if (symname(ssname, YES)==0) {
  209.     error("illegal function or declaration");
  210.     kill();            /* invalidate line */
  211.     return;
  212.     }
  213.   if(func1) {
  214.     postlabel(beglab);
  215.     func1=0;
  216.     }
  217.   if(ptr=findglb(ssname)) {    /* already in symbol table ? */
  218.     if(ptr[IDENT]!=FUNCTION)       multidef(ssname);
  219.     else if(ptr[OFFSET]==FUNCTION) multidef(ssname);
  220.     else {
  221.       /* earlier assumed to be a function */
  222.       ptr[OFFSET]=FUNCTION;
  223.       ptr[CLASS]=STATIC;
  224.       }
  225.     }
  226.   else
  227.     addsym(ssname, FUNCTION, CINT, FUNCTION, &glbptr, STATIC);
  228.   if(match("(")==0) error("no open paren");
  229.   entry();
  230.   locptr=STARTLOC;
  231.   argstk=0;            /* init arg count */
  232.   while(match(")")==0) {    /* then count args */
  233.     /* any legal name bumps arg count */
  234.     if(symname(ssname, YES)) {
  235.       if(findloc(ssname)) multidef(ssname);
  236.       else {
  237.         addsym(ssname, 0, 0, argstk, &locptr, AUTOMATIC);
  238.         argstk=argstk+BPW;
  239.         }
  240.       }
  241.     else {error("illegal argument name");junk();}
  242.     blanks();
  243.     /* if not closing paren, should be comma */
  244.     if(streq(lptr,")")==0) {
  245.       if(match(",")==0) error("no comma");
  246.       }
  247.     if(endst()) break;
  248.     }
  249.   csp=0;            /* preset stack ptr */
  250.   argtop=argstk;
  251.   while(argstk) {
  252.     /* now let user declare what types of things */
  253.     /*      those arguments were */
  254.     if(amatch("char",4))     {doargs(CCHAR);ns();}
  255.     else if(amatch("int",3)) {doargs(CINT);ns();}
  256.     else {error("wrong number of arguments");break;}
  257.     }
  258.   statement();
  259. #ifdef STGOTO
  260.   if(lastst != STRETURN && lastst != STGOTO) ffret();
  261. #else
  262.   if(lastst != STRETURN) ffret();
  263. #endif
  264.   if(litptr) {
  265.     printlabel(litlab);
  266.     col();
  267.     dumplits(1);        /* dump literals */
  268.     }
  269.   }
  270.  
  271. /*
  272. ** declare argument types
  273. **
  274. ** called from "newfunc" this routine adds an entry in the
  275. ** local symbol table for each named argument
  276. */
  277. doargs(t) int t; {
  278.   int j, legalname;
  279.   char c, *argptr;
  280.   while(1) {
  281.     if(argstk==0) return;    /* no arguments */
  282.     if(match("(*")|match("*")) j=POINTER;  else j=VARIABLE;
  283.     if((legalname=symname(ssname, YES))==0) illname();
  284.     if(match(")")) ;
  285.     if(match("()")) ;
  286.     if(match("[")) {
  287.       paerror(j);
  288.       while(inbyte()!=']') if(endst()) break;    /* skip "[...]" */
  289.       j=POINTER;        /* add entry as pointer */
  290.       }
  291.     if(legalname) {
  292.       if(argptr=findloc(ssname)) {
  293.         /* add details of type and address */
  294.         argptr[IDENT]=j;
  295.         argptr[TYPE]=t;
  296.         putint(argtop-getint(argptr+OFFSET, OFFSIZE), argptr+OFFSET, OFFSIZE);
  297.         }
  298.       else error("not an argument");
  299.       }
  300.     argstk=argstk-BPW;        /* cnt down */
  301.     if(endst())return;
  302.     if(match(",")==0) error("no comma");
  303.     }
  304.   }
  305.  
  306.